package com.hk.employeemanagementsystem.filter;

import com.hk.employeemanagementsystem.service.impl.SecurityService;
import com.hk.employeemanagementsystem.util.jwt.JwtTokenUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author by 何坤
 * @Classname JwtAuthorizationTokenFilter
 * @Description TODO
 * @Date 2019/12/5 14:33
 */
@Component
public class JwtAuthorizationTokenFilter extends OncePerRequestFilter {
    private Logger logger = LoggerFactory.getLogger(JwtAuthorizationTokenFilter.class);
    private final SecurityService securityService;
    private final JwtTokenUtil jwtTokenUtil;
    private final String tokenHeader;
    private final String tokenStartWith;

    public JwtAuthorizationTokenFilter(SecurityService securityService,
                                       JwtTokenUtil jwtTokenUtil,
                                       @Value("${jwt.token}") String tokenHeader,
                                       @Value("${jwt.startWith}") String tokenStartWith){
        this.securityService  = securityService;
        this.jwtTokenUtil = jwtTokenUtil;
        this.tokenHeader = tokenHeader;
        this.tokenStartWith = tokenStartWith;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest,
                                    HttpServletResponse httpServletResponse,
                                    FilterChain filterChain) throws ServletException, IOException {
        final String requestHeader = httpServletRequest.getHeader(this.tokenHeader);
        String username = null;
        String authToken = null;
        if (requestHeader != null && requestHeader.startsWith(tokenStartWith)) {
            authToken = requestHeader.substring(tokenStartWith.length());
            username = jwtTokenUtil.getUsernameFromToken(authToken);
        }
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.securityService.loadUserByUsername(username);
            if (jwtTokenUtil.validateToken(authToken, userDetails)) {
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        }
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}
